# Maintainer: Antoine Martin (ayakael) <dev@ayakael.net>
# Contributor: Antoine Martin (ayakael) <dev@ayakael.net>

#
# This is generated from dotnet31-build's APKBUILD.
# Any modifications to be done in that APKBUILD and propagated by
# executing 'abuild _update_bootstrap'
#
# Variables for dotnet build version 3.1
# This APKBUILD is designed to be the same for version 5.0 and under
# except for the variables in this first section
#

pkgname=dotnet31-bootstrap
pkgver=3.1.416
pkgrel=0

# Tag of tarball generator. This may change from usual due to mistakes from upstream
_installertag="v$pkgver-SDK"

# Tag of SBRP builder for dotnet 3.1
_sbrptag=045b2888ccfaf4c203c945a09b3f41f0e6393d1c

# this should match what is sourced by source-build's ./prep.sh script
# and, at the very least, the artifacts version sourced, as defined in
# eng/Version.Details.xml by var PrivateSourceBuiltArtifactsPackageVersion
# Sometimes, this needs updating by stage0 scripts, thus it is bumped from this
# version to establish that we are moving away from upstream
_bootstrapver=3.1.416-r0

# LLVM version to be used for this build
_llvmver=12

# Patches to be used. String before '_' refers to repo to patch
# Look for patch notes within each patch for what they fix / where they come from
# build_* patches applies directly to $builddir
_patches="
	application-insights_fix-net40-location.patch
	build_darc-fix-alpine.patch
	build_ignore-warnings.patch
	build_musl-build.patch
	cli_add-zsh-compdef-completion-script.patch
	coreclr_non-portable-distrorid-fix-alpine.patch
	core-sdk_generate-layout-core-setup-blob-path-fix.patch
	core-setup_rid-plat-generation-on-alpine-fix.patch
	corefx_fix-build-clang10.patch
	corefx_added-alpine-315-rid.patch
	references_sh-build-fix.patch
	"
# Custom prepare
default_prepare() {
	return
}

# Following for for dotnet builds version 5.0 and under
_pkgver_macro=${pkgver%.*}
_pkgver_prior=${pkgver%.*.*}
_pkgver_name=${_pkgver_macro//[.0]}
pkgdesc="The .NET $_pkgver_macro SDK"
arch="x86_64"
case $CARCH in
	x86_64) _dotnet_arch=x64;;
	aarch64) _dotnet_arch=arm64;;
	armv7) _dotnet_arch=arm;;
esac
url=https://www.microsoft.com/net/core
license="MIT"
_bootstrappkg="stage0"
makedepends="
	bash
	clang
	cmake
	dotnet$_pkgver_name-$_bootstrappkg=$_bootstrapver
	dotnet$_pkgver_name-$_bootstrappkg-artifacts=$_bootstrapver
	findutils
	git
	grep
	icu-dev
	inetutils-syslogd
	krb5-dev
	libgit2-dev
	libintl
	libunwind-dev
	libxml2-dev
	libxml2-utils
	linux-headers
	lldb-dev
	llvm$_llvmver-dev
	lttng-ust-dev
	nodejs
	openssl-dev
	zlib-dev
	"
options="!check" # No test suite

# packages artifacts if building bootstrap
[ "$_bootstrappkg" = "stage0" ] && subpackages="$pkgname-artifacts"

source="
	source-build-$_installertag.tar.gz::https://github.com/dotnet/source-build/archive/refs/tags/$_installertag.tar.gz
	source-build-reference-packages-$_sbrptag.tar.gz::https://github.com/dotnet/source-build-reference-packages/archive/$_sbrptag.tar.gz
	$_patches
	"
builddir="$srcdir/source-build-${_installertag/v}"
_sbrpdir="$srcdir"/source-build-reference-packages-$_sbrptag
_artifactsdir="/usr/share/dotnet/artifacts/${_bootstrapver%-*}"
_referencesdir="/usr/share/dotnet/artifacts/${_bootstrapver%-*}/SourceBuildReferencePackages"
_cli_root="$srcdir"/bootstrap

# Custom patch logics for dotnet version 5.0 and under
_patch() {
	local i failed=
	if ! have_patches; then
		return 0
	fi
	[ -d "$builddir" ] || { error "Is \$builddir set correctly?"; return 1; }
	msg "Deploying patches"
	for i in $source; do
		case ${i%::*} in
			build_*.patch)
				echo "applying $i to sourcebuild"
				patch ${patch_args:--p1} -i "$srcdir/$(filename_from_uri $i)" || failed="$failed $i"
			;;
			references_*.patch)
				echo "applying $i to references"
				cd "$_sbrpdir"
				patch ${patch_args:--p1} -i "$srcdir/$(filename_from_uri $i)" || failed="$failed $i"
			;;
			*.patch)
				local _package=$(echo $i | sed 's|_.*||')
				local _patch=$(echo $i | sed "s|$_package\_||")
				echo "deploying $_patch to $_package for application by sourcebuild"
				[ -d patches/$_package ] || mkdir patches/$_package
				cp "$srcdir"/"$i" patches/$_package/$_patch
			;;
		esac
	done

	if [ -z "$failed" ]; then
		return 0
	fi
	error "The following patches failed to apply:"
	for i in $failed; do
		printf "  %s\n" "$i"
	done
}

# aport for bootstrap is effectively a copy of this aport, except that it
# builds using stage0 bits, which are sourced from Microsoft prebuilts.
# Another major difference is that rather than package build artifacts
# under $dotnet_path/build to be packages later, it send artifacts to
# $dotnet_path/bootstrap, as this is the directory that is sourced by
# _prepare_bootstrap for build.
_update_bootstrap() {
	msg "Updating bootstrap APKBUILD"
	# Copy patches
	rm ../dotnet$_pkgver_name-bootstrap/*.patch || true
	for i in ../dotnet"$_pkgver_name"-build/*.patch; do
		cp $i ${i/$_pkgver_name-build/$_pkgver_name-bootstrap}
	done

	# Generate bootstrap
	{
		echo -n "# "
		echo "Maintainer: Antoine Martin (ayakael) <dev@ayakael.net>"
		echo "# Contributor: Antoine Martin (ayakael) <dev@ayakael.net>"
		echo
		echo "#"
		echo "# This is generated from dotnet$_pkgver_name-build's APKBUILD."
		echo "# Any modifications to be done in that APKBUILD and propagated by"
		echo -n "# executing 'abuild _update_bootstrap'"
		sed \
			-e "s/pkgname=dotnet$_pkgver_name-build/pkgname=dotnet$_pkgver_name-bootstrap/" \
			-e "s/_bootstrappkg=\"bootstrap\"/_bootstrappkg=\"stage0\"/" \
			-e "1,2d" \
			../dotnet$_pkgver_name-build/APKBUILD
	} > ../dotnet$_pkgver_name-bootstrap/APKBUILD
}

# dotnet relies on itself when building, we thus need a bootstrap runtime
# that is copied to write-capable folder
_prepare_bootstrap() {
	msg "Settings up bootstrap"
	cp -r /usr/share/dotnet/bootstrap/${_bootstrapver%-*} "$_cli_root"

	# Corrupt libcoreclrtraceptprovider.so when lttng <=2.13.0
	# is detected as tracing is broken on dotnet platform
	# due to ABI changes
	# See https://github.com/dotnet/runtime/issues/57784.
	if [ -f "/usr/lib/liblttng-ust.so.1 " ]; then
		rm "$_cli_root"/shared/Microsoft.NETCore.App/*/libcoreclrtraceptprovider.so
	fi
}

# Build doesn't set all the right executable bits for the right file types
_fix_executable() {
	# add executable bit
	find "$1" -type f \( \
		-name 'apphost' -o \
		-name 'singlefilehost' -o \
		-name 'lib*so' \
			\) \
		-exec chmod +x '{}' \;

	# remove executable bit
	find "$1" -type f \( \
		-name '*.a' -o \
		-name '*.dll' -o \
		-name '*.h' -o \
		-name '*.json' -o \
		-name '*.pdb' -o \
		-name '*.props' -o \
		-name '*.pubxml' -o \
		-name '*.targets' -o \
		-name '*.txt' -o \
		-name '*.xml' \
			\) \
		-exec chmod -x '{}' \;
}

prepare() {
	default_prepare

	# source-build expects to be in a git repo
	git init
	git add ./*
	git commit -m 'initial commit'
	git remote add origin https://github.com/dotnet/source-build.git

	_patch
	_prepare_bootstrap

	# by default build populates these folders using Artifacts and SBRP archives
	# we are instead going to populate them from the prebuilt artifacts provided
	# by dotnetx-bootstrap-artifacts
	[ -f "$builddir/packages" ] || mkdir -p "$builddir"/packages
	cp -r "$_artifactsdir" "$builddir"/packages/prebuilt
	mv "$builddir"/packages/prebuilt/SourceBuildReferencePackages "$builddir"/packages/reference
	# make sure archives wont be downloaded or aren't expected.
	[ -d "$builddir"/packages/archive ] && rm -r "$builddir"/packages/archive

	# by default, coreclr-tools is not sourced from dotnetx-bootstrap-artifacts, thus
	# it'll be the wrong architecture. Below replaces default coreclr-tools with
	# versions from artifacts, which have been built properly
	mkdir -p "$builddir"/Tools/source-built
	cp -r "$builddir"/packages/prebuilt/coreclr-tools "$builddir"/Tools/source-built/.
}

build() {
	msg "Building $pkgname-$pkgver"

	# logs args, else the output is forwarded to log files which isn't ideal in a
	# pipeline environment
	local args="
		/v:n
		/p:LogVerbosity=n
		/p:MinimalConsoleLogOutput=false
		"

	# defaults args for build on Alpine
	local args="$args
		/p:SkipDownloadingPreviouslySourceBuiltPackages=true
		/p:SkipDownloadingReferencePackages=true
		/p:ContinueOnPrebuiltBaselineError=true
		/p:SkipPrebuiltEnforcement=true
		/p:UseSystemLibraries=true
		/p:UseSystemLibunwind=true
		"

	./build.sh \
		--with-sdk "$_cli_root" \
		$args | tee -a build.log

	# only build references when building with stage0
	[ "$_bootstrappkg" = "bootstrap" ] && return

	msg "Building source build reference packages"
	cd "$_sbrpdir"
	./build.sh \
		--with-sdk "$_cli_root" \
		--with-packages "$builddir"/artifacts/$_dotnet_arch/Release/Private.SourceBuilt.Artifacts.0.1.0-dev.tar.gz \
		| tee -a build.log
}

package() {
	local subdir=${pkgname/*-}
	local targetdir="$pkgdir"/usr/share/dotnet/$subdir/$pkgver

	# directory creation
	install -dm 755 \
		"$targetdir"/docs \
		"$targetdir"/comp

	# unpack build artifacts to subdir defined by pkgname. If bootstrap, unpacks
	# to bootstrap, if build unpacks to build
	tar -xzf "$builddir"/artifacts/$_dotnet_arch/Release/dotnet-sdk-$_pkgver_macro*.tar.gz -C "$targetdir"/ --no-same-owner

	# assemble completions
	install -m 755 "$builddir"/artifacts/src/cli.*/scripts/register-completions.bash "$targetdir"/comp/
	install -m 755 "$builddir"/artifacts/src/cli.*/scripts/register-completions.zsh "$targetdir"/comp/

	# assemble docs
	find "$builddir" -iname 'dotnet*.1' -type f -exec cp '{}' "$targetdir"/docs/ \;

	# some files either should or should not have executable bits
	_fix_executable "$pkgdir"

	# See https://github.com/dotnet/source-build/issues/2579
	find "$pkgdir" -type f -name 'testhost.x86' -delete
	find "$pkgdir" -type f -name 'vstest.console' -delete
}

# build relies on a plethora of nupkgs which are provided by this Artifacts file.
# stage0 sources these from Microsoft, which then allows bootstrap to build
# locally hosted versions. The following unpacks built tarball into directory
# for use by future builds.
artifacts() {
	pkgdesc="Internal package for building .NET $_pkgver_macro Software Development Kit"

	# directory creation
	install -dm 755 \
		"$subpkgdir"/usr/share/dotnet/artifacts/$pkgver/SourceBuildReferencePackages \
		"$subpkgdir"/usr/share/licenses

	# extract artifacts to artifacts dir for use by future dotnet builds
	tar -xzf "$builddir"/artifacts/$_dotnet_arch/Release/Private.SourceBuilt.Artifacts.*.tar.gz -C "$subpkgdir"/usr/share/dotnet/artifacts/$pkgver/ --no-same-owner \
		--exclude '*Intermediate*'

	# pulls SBRP artifacts
	install -m 644 "$_sbrpdir"/artifacts/reference-packages/* "$subpkgdir"/usr/share/dotnet/artifacts/$pkgver/SourceBuildReferencePackages/.
}

sha512sums="
651c59c44ec2492efbcbea86e1c42f27add2ea9dbe76d4123d24ee868538c707e82e3c7538f2183a6482e62f1038475af46717005938d77c7900ae3a5a1cc3a7  source-build-v3.1.416-SDK.tar.gz
9d7ae29c311cd9550389225cab891df359385e098aaccb8100c77832ea7b7b1f6a7984d811cb1f45bd323182149246c33f2016b4ee85d97ee9b29243acc644bc  source-build-reference-packages-045b2888ccfaf4c203c945a09b3f41f0e6393d1c.tar.gz
1ef3cb59231b7462167f782cbfcacee4a7bc7d73ec635de4ea3f4510cc6d46c5548ce2ec2ce3d3943bf6d1c29cb288dc1c82f1b22fe1c61fb6013e2df728467e  application-insights_fix-net40-location.patch
f945552c083828e80031bdae584514aa8e7eb64544cc1fc3ca658a4162303f2a1caf076f44bc567c34ed2cf4c42323eaaafae0719adf9855756af125a566e99b  build_darc-fix-alpine.patch
bd28775f37c9d448eab52922d0b8e0a6a32a3e16f772337850c48bd886e0302f97423b7b58dbc010c30764772f0bc00115ace72422dd12f447a5282ae62da4b3  build_ignore-warnings.patch
e2a63a9c262a95698eba5639a32eb8ba968a3d4c1fb70ea9890f3915e9923190a4aabed0ef74d64cb5199ee9d06c77736d36861ed8418ab8638552763c2c58b5  build_musl-build.patch
55afa9c74be6f5a87f1ff5aa44caad094cf620eb4388f6407218acf3d58a878f5565a0e875e95c3dbe0efca1879c120ee4b8076c521bfc9d6069a652c4a4fdd8  cli_add-zsh-compdef-completion-script.patch
dcbb3824acb432739b08d329a5b2f95a32d806bdb4a11d3cdd0245724e6ee92ee85bbf30f5a0f6607598f5252cd9cdaf92cea5101d33b4bf5161b7b22b853c0e  coreclr_non-portable-distrorid-fix-alpine.patch
5dffe94647daebd0a56ffd63db7f7f64ac7c4b279aa7189396d792fe4143989a91ffdb86f687dea3caa2475ac2ad43b95abcddacd175fef392bd24b52c957964  core-sdk_generate-layout-core-setup-blob-path-fix.patch
8f2de7774a62c846a3c5806a2a6fa651930f30dc91f06fac7a8dc9032cb1fb8bbff6bdd833fc0767effcd35751ee43a4ca059fced926f2cd9f970c88dd7271eb  core-setup_rid-plat-generation-on-alpine-fix.patch
2e05046b087670ff95c9df585b0d5d153518e1b2d7abc3288217e067728620fb85bf9bd8ec1541433fdae694fcb11dacaf5448fa4acd812afcfaa869f17e7fcd  corefx_fix-build-clang10.patch
2fd67942f2f93e950e5977296b553ebbd9316f9e9be380a74673e18836bacebfa005cab0d6e8f02d1dd4a67a92d6d526522393dd2fa8b7bc22f1165af87b7dac  corefx_added-alpine-315-rid.patch
441528c42256f30dda83854f78d53d2507b6e7a159aea4456c3872a8be3690f8f222709a6ec70503cd1875d7d8c2f43d7a54ef0c30761fbdfc3c2a394136f7fc  references_sh-build-fix.patch
"
